/**
 * JAVACC DEMO 1.0
 */
package com.apache.portal.filter;

import com.apache.api.vo.ResultEntity;
import com.apache.passport.common.PassportHelper;
import com.apache.portal.common.oscache.BaseOsCache;
import com.apache.portal.common.oscache.OsCacheManager;
import com.apache.portal.common.oscache.OsCacheOtherManager;
import com.apache.rpc.common.LoadRpcService;
import com.apache.rpc.common.RpcUtil;
import com.apache.rpc.entity.InterfaceRegister;
import com.apache.tools.StrUtil;
import com.apache.uct.common.ToolsUtil;
import com.apache.uct.common.filter.UctSupperFilter;
import net.sf.json.JSONObject;
import org.apache.log4j.Logger;

import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * description:  portal父级过滤器
 *
 * @author dyhou 创建时间：2017-7-28
 */
public abstract class PortalPubSuperFilter extends UctSupperFilter {

    protected Logger log = Logger.getLogger(getClass());

    protected static final String SUFFIX = "js,css,png,jpg,gif,bmp,swf,fla,ico";

    //sso登录页面
    protected String login_url = "";

    //定自义登录页面
    protected String customLogin = "";

    //cookieName 名称
    protected String cookieName = "";

    //获取系统名称
    protected String sysEname = "";

    //是否使用统一登录系统登录 T/F
    protected String login_pass = "";

    protected String reqUrl = "";

    //http,socket,https,webservice
    protected String reqType = "";

    protected String checkIp = "";

    protected String checkPort = "";

    protected String isClearSession = "";

    //系统名称
    protected String sessionKey = "loginUser";

    //错误页面地址
    protected String errorPage = "";

    protected BaseOsCache oscache;

    private InterfaceRegister register;

//    private String[] inj_str = { "select ", "(select", "insert ", "drop ", "union ", "delete ",
//            "update ", "+and+", " and ", "+or+", " or ", "'='", "<script", "confirm(", "prompt(",
//            "eval(", "function(", "alert(", ":alert", "ltrim(", "[window[", "<iframe", "<a href",
//            "<input ", "<img", "<audio", "onerror\\=", "ltrim(", "{tostring:", "</script",
//            "</style", "href=", "vbscript", "vbjavascript"};
    private String[] inj_str = { "<script", "confirm(", "prompt(",
            "eval(", "function(", "alert(", ":alert", "ltrim(", "[window[", "<iframe", "<a href",
            "<input ", "<img", "<audio", "onerror\\=", "ltrim(", "{tostring:", "</script",
            "</style", "href="};
    private Pattern p;

    private Matcher m;

    public void destroy() {

    }

    public void init(FilterConfig arg0) throws ServletException {
        sysCode = "portal";
        //XmlWhiteUtils.getInstance().deWhiteXml(whiteMap);//加载白名单
        initValue();
        errorPage = StrUtil.doNull(arg0.getInitParameter("errorPage"), "/error.action");
        oscache = OsCacheOtherManager.getInstance().getBaseOsCache("sso_token_", 300);
        //        StartSocketPortListener dd = new StartSocketPortListener();
        String rpcVersion = ToolsUtil.getInstance()
                .getValueByKey("config.properties", "rpc.version");
        if (StrUtil.isNotNull(rpcVersion)) {
            RpcUtil.getInstance().setVersion(rpcVersion);//.setVersion(rpcVersion);
        }
    }

    protected void initValue() {
        customLogin = ToolsUtil.getInstance().getValueByKey("custom_login");
        //自定义登录页面
        login_url = ToolsUtil.getInstance().getValueByKey("uct_server");
        //cookieName 名称
        cookieName = ToolsUtil.getInstance().getValueByKey("cookieName");
        //获取系统名称
        sysEname = ToolsUtil.getInstance().getValueByKey("sysEname");
        //是否使用统一登录系统登录 T/F
        login_pass = ToolsUtil.getInstance().getValueByKey("login.pass");
        reqUrl = ToolsUtil.getInstance().getValueByKey("req_url");
        //http,socket,https,webservice
        reqType = ToolsUtil.getInstance().getValueByKey("req_type");
        checkIp = ToolsUtil.getInstance().getValueByKey("check_url");
        checkPort = ToolsUtil.getInstance().getValueByKey("check_port");
        isClearSession = ToolsUtil.getInstance().getValueByKey("is_clear_session");
        String inj_str_config = ToolsUtil.getInstance().getValueByKey("security_filter_strs");
        if(!StrUtil.isNull(inj_str_config)){
            inj_str=inj_str_config.split(",");
        }
    }

    /**
     * description:  发送数据信息
     */
    protected JSONObject ssoSend(String tokenCookie, String ip, String methodCode,
            String userEname) {
        Map<String, Object> maps = new HashMap<String, Object>();
        if (StrUtil.isNotNull(userEname))
            maps.put("userEname", userEname);
        maps.put("tokenId", tokenCookie);
        maps.put("sysEname", sysEname);
        maps.put("sysAccreditip", ip);
        ResultEntity entity = LoadRpcService.service()
                .doServiceClient("ssoService", methodCode, maps, getInterfaceRegister());
        JSONObject json = JSONObject.fromObject(entity);
        return json;
    }

    private InterfaceRegister getInterfaceRegister() {
        if (null == register) {
            register = new InterfaceRegister();
            String type = StrUtil
                    .doNull(reqType, ToolsUtil.getInstance().getValueByKey("req_type"));
            String ip = StrUtil.doNull(checkIp, ToolsUtil.getInstance().getValueByKey("check_url"));
            if ("socket".equals(type)) {
                String port = StrUtil
                        .doNull(checkPort, ToolsUtil.getInstance().getValueByKey("check_port"));
                register.setAddress(ip);
                register.setPort(port);
                register.setCallType("socket");
            } else {
                String ssoPath = StrUtil
                        .doNull(reqUrl, ToolsUtil.getInstance().getValueByKey("req_url"));
                register.setAddress(ssoPath);
                if (ssoPath.startsWith("https:"))
                    register.setCallType("https");
                else {
                    register.setCallType("http");
                }
            }
        }
        return register;
    }

    /**
     * description:  清空本地cookie
     */
    protected void clearCookie(HttpServletRequest request, HttpServletResponse response,
            String path) {
        Cookie[] cookies = request.getCookies();
        String tokenCookie = PassportHelper.getInstance().getCurrCookie(request);
        try {
            if (null != cookies && cookies.length > 0) {
                for (int i = 0; i < cookies.length; i++) {
                    Cookie cookie = new Cookie(cookies[i].getName(), null);
                    cookie.setMaxAge(0);
                    cookie.setPath("/");
                    cookie.setPath(path);//根据你创建cookie的路径进行填写
                    response.addCookie(cookie);
                }
            }
        } catch (Exception ex) {
            log.warn("msg:[清空Cookies发生异常!]");
            ex.printStackTrace();
        }
        String seTokenId = String.valueOf(oscache.get(request.getSession().getId()));
        seTokenId = StrUtil.doNull(seTokenId, tokenCookie);
        if (StrUtil.isNotNull(seTokenId)) {
            oscache.remove(seTokenId);
            oscache.remove(request.getSession().getId());
            oscache.remove("checkToken_" + seTokenId);
            OsCacheManager.getInstance().removeLoginUser(seTokenId);
        }
        if (!"0".equals(isClearSession)) {
            Enumeration enumer = request.getSession().getAttributeNames();
            while (enumer.hasMoreElements()) {
                request.getSession().removeAttribute(enumer.nextElement().toString());
            }
            request.getSession().invalidate();
        }
    }

    protected void sendErrorPage(HttpServletRequest request, HttpServletResponse response) {
        String header = request.getHeader("X-Requested-With");
        boolean isAjax = "XMLHttpRequest".equals(header);
        try {
            if (isAjax) {
                response.setContentType("text/html;charset=utf-8");
                PrintWriter writer = response.getWriter();
                writer.write("{\"flag\":\"F\",\"msg\":\"非法请求！\"}");
                writer.flush();
                writer.close();
            } else {
                request.setAttribute("errors", "警告！非法请求！！");

                request.getRequestDispatcher("/common/error.jsp").forward(request, response);
            }
        } catch (Exception localException) {
        }
    }

    protected boolean checkSecurity(HttpServletRequest request) {
        String pui = request.getRequestURI();
        if ((pui.toLowerCase().contains("/owa_util.signature")) || (pui.toLowerCase()
                .contains("/sqlnet.trc"))) {
            log.error("非法请求参数=" + pui);
            return true;
        }
        if (StrUtil.isNotNull(request.getParameter("formToken"))) {
            return false;
        }
        String is_open_security_filter = ToolsUtil.getInstance().getValueByKey("is_open_security_filter");
        log.warn("是否开启安全拦截过滤[is_open_security_filter]："+is_open_security_filter);
        if ("true".equalsIgnoreCase(is_open_security_filter)) {//是否开启安全过滤
            String str = request.getQueryString();
            log.info("request.getQueryString->"+str);
            if (StrUtil.isNull(str)) {
                Enumeration params = request.getParameterNames();
                while (params.hasMoreElements()) {
                    String name = (String) params.nextElement();
                    String[] value = request.getParameterValues(name);
                    for (int i = 0; i < value.length; i++) {
                        str = str + value[i];
                    }
                }
            }
            str = request.getHeader("Referer") + str;
            if (StrUtil.isNull(str))
                return false;
            String sql = str.toLowerCase();
            sql = sql.replace("%28", "(").replace("%2b", "+").replace("%3c", "<")
                    .replace("%27", "'").replace("%5b", "[").replace("%5d", "]").replace("%3d", "=")
                    .replace("%7c", "|").replace("%7b", "{").replace("%3a", ":").replace("%2f", "/")
                    .replace("%20", " ");

            for (int i = 0; i < this.inj_str.length; i++) {
                if (sql.indexOf(this.inj_str[i]) >= 0) {
                    log.error("非法请求参数地址=" + sql+", 拦截的关键词="+ this.inj_str[i]);
                    return true;
                }
            }
            return isEqualString(sql);
        }
        return false;
    }

    private boolean isEqualString(String str) {
        String regEx_style = "(<[a-zA-Z].*?>)|(<[\\/][a-zA-Z].*?>)";
        this.p = Pattern.compile(regEx_style);
        this.m = this.p.matcher(str);
        return this.m.matches();
    }
}
